<?php

namespace App\Acl;

use Phalcon\Acl\Resource;
use \Phalcon\Acl\Role;

/**
 * 访问控制列表管理器
 * @package App\Acl
 */
class AclList extends \Phalcon\Acl\Adapter\Memory {

    #region 属性

    /**
     * \Phalcon\Di 对象
     * @var \Phalcon\Di
     */
    protected static $di;

    /**
     * \Phalcon\Config 对象
     * @var \Phalcon\Config
     */
    protected static $config;

    /**
     * 已加入访问控制的资源列表
     * @var array
     */
    protected $resources = array();

    #endregion

    #region 常量

    #region 角色相关

    /**
     * 角色配置关键字
     * @var string
     */
    const ROLES = "roles";

    /**
     * 已实名认证用户
     */
    const IDENTITY = "identity";

    /**
     * 主播
     */
    const ANCHOR = "anchor";

    /**
     * 聊天室房管
     */
    const ROOM_MANAGER = "room_manager";

    /**
     * 已授权发布可售商品
     */
    const SALE = "sale";

    /**
     * 分组管理员
     */
    const GROUP_MANAGER = "group_manager";

    /**
     * 分组成员
     */
    const GROUP_MEMBER = "group_member";

    /**
     * 一般用户
     */
    const GENERAL = "general";

    #endregion

    #region 资源相关

    /**
     * 资源配置关键字
     */
    const RESOURCES = "resources";

    #endregion

    #region 访问控制

    /**
     * 资源配置关键字
     */
    const ACCESS_CONTROLS = "accessControls";

    #endregion

    #endregion

    #region 初始化访问控制列表管理器对象

    /**
     * 初始化访问控制列表管理器对象
     * @param  \Phalcon\Di $di \Phalcon\Di 对象
     * @return AclList
     */
    static function init(\Phalcon\Di $di) {

        self::$di = $di;

        //　运行环境时，使用缓存
        if (BUILD_VERSION == BUILD_RELEASE) {

            /**
             * @var \App\Interfaces\ICache $cache 缓存对象
             */
            $cache = self::$di->getShared("cache");
            $acl = $cache->getAclList();
        }

        if (!isset($acl) || !$acl) {
            /**
             * 控制列表数据
             */
            $aclConfig = include APP_PATH . "/app/config/acl.php";

            $acl = new AclList();
            //  设置默认访问级别为允许
            $acl->setDefaultAction(\Phalcon\Acl::ALLOW);

            // 添加角色都ACL
            $acl->addRoles($aclConfig[self::ROLES]);
            // 添加资源都ACL
            $acl->addResources($aclConfig[self::RESOURCES]);
            // 定义访问控制
            $acl->defineAccessControls($aclConfig[self::ACCESS_CONTROLS]);

            //　运行环境时，使用缓存
            if (BUILD_VERSION == BUILD_RELEASE) {
                $cache->setAclList($acl);
            }
        }
        return $acl;
    }

    #endregion

    #region 添加相关数据到ACL

    #region 添加角色到ACL

    /**
     * 添加角色到ACL
     * @param $roles 角色信息
     */
    function addRoles($roles) {
        foreach ($roles as $name => $desc) {
            $this->addRole(new Role($name, $desc));
        }
    }

    #endregion

    #region 添加资源到ACL

    /**
     * 添加资源到ACL
     * @param $resources 资源信息
     */
    function addResources($resources) {
        $this->resources = $resources;
        foreach ($resources as $name => $data) {
            $resource = new Resource($name, $data["desc"]);
            $this->addResource($resource, $data["actions"]);
        }
    }

    #endregion

    #region 定义访问控制

    /**
     * 定义访问控制
     * @param $accessControls 访问控制数据
     */
    function defineAccessControls($accessControls) {
        foreach ($accessControls as $role => $data) {
            foreach ($data as $method => $resources) {
                foreach ($resources as $resource => $actions) {
                    $this->$method($role, $resource, $actions);
                }
            }
        }
    }

    #endregion

    #endregion

    #region 获取属性值

    /**
     * 获取属性值
     * @param 属性名
     * @return array
     */
    function __get($name) {
        if (isset($this->$name)) {
            return $this->$name;
        }
        return null;
    }

    #endrergion
}